#pragma once

#include "internal/sdeque.h"
#include "BaseOrder.h"

namespace mdtx::punch
{
    template <class QT>
    class BaseBook
    {
    public:
        using order_type = BaseOrder<QT>;
        using id_type = typename QT::id_type;

        using bid_queue_type = internal::sdeque<QT, typename QT::BidComparator>;
        using ask_queue_type = internal::sdeque<QT, typename QT::AskComparator>;

        /**
         * @brief Get number of order
         *
         * @param ins_id instrument id
         * @return size_t
         */
        virtual size_t num_order(id_type ins_id) const = 0;

        /**
         * @brief Create a new order in book
         *
         * @param ins_id instrument id
         * @param order order
         * @return order_type& reference to new order created
         */
        virtual order_type &new_order(id_type ins_id, const order_type &order) = 0;

        /**
         * @brief Get bid queue
         *
         * @param ins_id instrument id
         * @return bid_queue_type&
         */
        virtual bid_queue_type &bid(id_type ins_id) = 0;

        /**
         * @brief Get bid queue
         *
         * @param ins_id instrument id
         * @return const bid_queue_type&
         */
        virtual const bid_queue_type &bid(id_type ins_id) const = 0;

        /**
         * @brief Get ask queue
         *
         * @param ins_id instrument id
         * @return ask_queue_type&
         */
        virtual ask_queue_type &ask(id_type ins_id) = 0;

        /**
         * @brief Get ask queue
         *
         * @param ins_id instrument id
         * @return const ask_queue_type&
         */
        virtual const ask_queue_type &ask(id_type ins_id) const = 0;

        /**
         * @brief Get order
         *
         * @param ins_id instrument id
         * @param seq_id sequence id
         * @return order_type&
         */
        virtual order_type &order(id_type ins_id, id_type seq_id) = 0;

        /**
         * @brief Get order
         *
         * @param ins_id instrument id
         * @param seq_id sequence id
         * @return const order_type&
         */
        virtual const order_type &order(id_type ins_id, id_type seq_id) const = 0;

        /**
         * @brief Callback on updates to order
         *
         * @param ins_id instrument id
         * @param order order
         */
        virtual void on_order(id_type ins_id, const order_type &order) {}

        virtual ~BaseBook() = default;
    };
}
